home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / dvitowin.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  19KB  |  847 lines

  1. #include <windows.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <math.h>
  8. #include <stdarg.h>
  9. #ifdef __TURBOC__
  10. #include <alloc.h>
  11. #else
  12. #define huge
  13. #endif
  14.  
  15. #define true (!false)
  16. #define false 0
  17. #include "dvipath.h"
  18.  
  19. #include "dviwin.h"
  20.  
  21. void metafile_fix(void );
  22.  
  23. void main_show(HWND hwnd);
  24. void do_convert(void) ;
  25. void do_display(void);
  26. int32 FAR PASCAL fnmainwnd(HWND hWnd, unsigned wMessage, WORD wParam, LONG lParam);
  27. int wprintf(char *fmt, ...);
  28. void emsg(char *s);
  29.  
  30. void draw_file(void);
  31. void gle_abort(char *s);
  32. void path_send();
  33. void path_fill(void);
  34. void path_clip(void);
  35. void path_send(void);
  36. void path_stroke(void);
  37. void path_move(int  x,int y);
  38. void path_line(int x,int y);
  39. void path_bezier(int x1, int y1, int x2, int y2,int x3, int y3);
  40. void path_closepath(void);
  41. void path_alloc(void);
  42. void path_free(void);
  43. void d_open(double width, double height);
  44. void d_close(void);
  45. void d_line(int cx,int cy,int x,int y);
  46. void d_lwidth(int width);
  47. void d_bezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
  48. void d_pbezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
  49. void d_newpath(void);
  50. void d_pmove(int x, int y);
  51. void d_pline(int x, int y);
  52. void d_pclose(void);
  53. void d_fill(void);
  54. void d_lstyle(int cur_lstyle,int dot);
  55. void d_setcolor(int r,int g,int b,int f);
  56.  
  57. double d_xscale, d_yscale;
  58. int gdebug=false;
  59. int fittobit;    /* true if picture should be scaled up to fit bitmap, wp-tiff */
  60. void do_delay(int tm);
  61.  
  62. #define XBITS 10000
  63. #define YBITS 10000
  64. #define scx(v) ( ((v) * d_xscale + 1))
  65. #define scy(v) ( ((v) * d_yscale + 1))
  66. int debug_flag = false;
  67. #define dbg if (debug_flag)
  68.  
  69. double devxcm,devycm;
  70. double uxcm,uycm;
  71.  
  72. /*---------------------------------------------------------------------------*/
  73. /*        Local stuff */
  74. int flipit;
  75. FILE *outbit;
  76. FILE *inf;
  77. #define TEMP_FILE "dviwin.tmp"
  78. #define OUT_FILE "gle.wmf"
  79.  
  80. /*---------------------------------------------------------------------------*/
  81. void main_usage(void)
  82. {
  83.     printf("Usage: dviprint [-depson | -dlj] [-old] [-hires] [-debug] [-output xx.prt]\n");
  84.     printf("\n");
  85. }
  86. char outbitname[80];
  87. char gleroot[90];
  88. HANDLE   hInst;
  89. HWND hwndmain;
  90. static int use_screen;
  91. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  92.     LPSTR  lpszCmdLine,int nCmdShow)
  93. {
  94.     char appname[]="dviwin";
  95.     MSG      msg;
  96.     WNDCLASS wndclass;
  97.     HANDLE hBorLibrary;
  98.  
  99.     hBorLibrary = LoadLibrary("bwcc.dll");
  100.  
  101.     hInst = hInstance;    // Store the application instance handle
  102.     if(!hPrevInstance) {
  103.       wndclass.style           = CS_HREDRAW | CS_VREDRAW;
  104.         wndclass.lpfnWndProc     =  fnmainwnd;
  105.       wndclass.cbClsExtra      = 0;
  106.       wndclass.cbWndExtra      = 0;
  107.       wndclass.hInstance       = hInstance;
  108.       wndclass.hCursor         = LoadCursor(NULL, IDC_ARROW);
  109.       wndclass.hIcon           = NULL;
  110.         wndclass.hbrBackground   = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  111.         wndclass.lpszMenuName    = "dviwin";
  112.       wndclass.lpszClassName   = appname;
  113.  
  114.         if(!RegisterClass(&wndclass)) return FALSE;
  115.         wndclass.lpszMenuName = NULL;
  116.         wndclass.hbrBackground   = 0;
  117.         wndclass.lpszClassName = "simple";
  118.         if(!RegisterClass(&wndclass)) return FALSE;
  119.     }
  120.  
  121.        if(!(hwndmain = CreateWindow(appname,
  122.                        "DVI to WINDOWS System",
  123.                        WS_OVERLAPPEDWINDOW,
  124.                        CW_USEDEFAULT, 0,
  125.                        CW_USEDEFAULT, 0,
  126.                        NULL, NULL, hInstance, NULL))) {
  127.  
  128.         return FALSE;
  129.        }
  130.  
  131.        ShowWindow(hwndmain, nCmdShow);
  132.        UpdateWindow(hwndmain);
  133.  
  134.     while(GetMessage(&msg, NULL, 0, 0)) {
  135.             TranslateMessage(&msg);
  136.         DispatchMessage(&msg);
  137.      }
  138.       if(hBorLibrary > 32) FreeLibrary(hBorLibrary);
  139.    return msg.wParam;
  140. }
  141.  
  142. int32 FAR PASCAL fnmainwnd(HWND hWnd, unsigned wMessage, WORD wParam, LONG lParam)
  143. {
  144.     switch(wMessage) {
  145.     case WM_COMMAND :
  146.         if(!LOWORD(lParam)) {           // Process Menu Commands
  147.              switch(wParam) {           // Determine which Menu ID
  148.                 case IDM_QUIT :
  149.                       PostQuitMessage(0);
  150.                break;
  151.                 case IDM_CONVERT :
  152.                 use_screen = false;
  153.                     do_convert();
  154.                break;
  155.                 case IDM_TEST:
  156.                 use_screen = true;
  157.                     do_convert();
  158.                break;
  159.                 case IDM_DISPLAY :
  160.                     do_display();
  161.                break;
  162.             case IDM_HELP :
  163.                     break;
  164.              }
  165.         } else {
  166.         }
  167.       break;
  168.      case WM_DESTROY :
  169.         PostQuitMessage(0);
  170.         break;
  171.       case WM_PAINT:
  172.          main_show(hWnd);
  173.       break;
  174.      default :
  175.          return DefWindowProc(hWnd, wMessage, wParam, lParam);
  176.    }
  177.    return 0L;
  178. }
  179.  
  180. void main_show(HWND hwnd)
  181. {
  182.     HDC hdc;
  183.     PAINTSTRUCT ps;
  184.     RECT rect;
  185.     HANDLE hmf;
  186.  
  187.  
  188.     hdc = BeginPaint(hwnd,&ps);
  189.     EndPaint(hwndmain,&ps);
  190.  
  191. }
  192.  
  193. void do_convert(void)
  194. {
  195.     //emsg("doing conversion");
  196.     //wprintf("Doing conversion");
  197.     inf = fopen("out.dvi","rb");
  198.     if (inf==NULL) {
  199.         printf("Unable to open OUT.DVI for input, run DVIGLE first\n");
  200.         gle_abort("");
  201.    }
  202.     draw_file();
  203.     fclose(inf);
  204. }
  205. void do_display(void)
  206. {
  207.     HDC hdc;
  208.     RECT rect;
  209.     HANDLE hmf;
  210.  
  211.     hdc = GetDC(hwndmain);
  212.  
  213.     GetClientRect(hwndmain,&rect);
  214.     SetMapMode(hdc,MM_ANISOTROPIC);
  215.     SetWindowExt(hdc,XBITS,YBITS);
  216.     SetViewportExt(hdc,rect.right,-rect.bottom);
  217.    SetViewportOrg(hdc,0,rect.bottom);
  218.  
  219.     hmf = GetMetaFile(TEMP_FILE);
  220.     PlayMetaFile(hdc,hmf);
  221.    DeleteMetaFile(hmf);
  222.     ReleaseDC(hwndmain,hdc);
  223. }
  224. /*---------------------------------------------------------------------------*/
  225. /*   Path variables for bitmap */
  226. int *path;
  227. int npath;
  228. int npath_alloc;
  229.  
  230. int file_end = false;
  231. float getf(void);
  232. int getfxy(int *x, int *y);
  233. int getfxy(int *x, int  *y)
  234. {
  235.     float u,xx,yy;
  236.     xx = getf();
  237.     yy = uycm - getf();
  238.  
  239.     if (flipit) {
  240.         u = yy;
  241.         yy = uxcm - xx;
  242.         xx = u;
  243.     }
  244.     /*printf("fxy %g %g \n",xx,yy); */
  245.     *x = (int) .5+scx(xx);
  246.     *y = (int) .5+scy(yy);
  247. }
  248. float getf(void)
  249. {
  250.     static float x;
  251.     fread(&x,sizeof(x),1,inf);
  252.     if (feof(inf)) file_end = true;
  253.     return x;
  254. }
  255. int32 getl(void)
  256. {
  257.     static int32 x;
  258.     fread(&x,sizeof(x),1,inf);
  259.     if (feof(inf)) file_end = true;
  260.     return x;
  261. }
  262.  
  263.  
  264. float cur_lwidth,cur_color,cur_fill,cur_dashlen;
  265. int32 cur_lstyle;
  266.  
  267. void draw_file(void)
  268. {
  269.     MSG msg;
  270.     int x2,y2,x3,y3,sx,sy;
  271.     int x,y,cx,cy;
  272.     int g=0;
  273.     float fx,fy;
  274.     int i,dot;
  275.  
  276.     for (;!file_end;) {
  277.      // for (;0!=PeekMessage((LPMSG) &msg,hwndmain,0,1000,PM_NOREMOVE);)
  278.       // {
  279.   //              TranslateMessage(&msg);
  280.     //        DispatchMessage(&msg);
  281.         //}
  282.       i = getl();
  283.       if (file_end) break;
  284.       switch (i) {
  285.         case p_size:
  286.             dbg wprintf("#size \n");
  287.             fx = getf(); fy = getf();
  288.             d_open(fx,fy);
  289.             dbg wprintf(":");
  290.         case p_newpath:
  291.             dbg wprintf("#newpath \n");
  292.             npath = 0;
  293.             break;
  294.         case p_move:
  295.             getfxy(&x,&y);
  296.             cx = x; cy = y;
  297.             dbg wprintf("#move (%d) %d %d  \n",npath,x,y);
  298.             path_move(x,y);
  299.             sx = cx; sy = cy;
  300.             break;
  301.         case p_line:
  302.             dbg {g++; if (g>200) {printf(":"); g=0;}}
  303.             getfxy(&x,&y);
  304.             cx = x; cy = y;
  305.             dbg wprintf("#line (%d) %d %d  \n",npath,x,y);
  306.             path_line(x,y);
  307.             break;
  308.         case p_closepath:
  309.             dbg wprintf("#closepath %d %d \n",sx,sy);
  310.             path_closepath();
  311.             cx = sx; cy = sy;
  312.             break;
  313.         case p_dline:
  314.             dbg {g++; if (g>200) {wprintf(":"); g=0;}}
  315.             getfxy(&x,&y);
  316.             d_line(cx,cy,x,y);
  317.             npath = 0;
  318.             dbg wprintf("#(nopath)line %d %d %d %d  \n",cx,cy,x,y);
  319.             cx = x; cy = y;
  320.             break;
  321.         case p_bezier:
  322.             getfxy(&x,&y);
  323.             getfxy(&x2,&y2);
  324.             getfxy(&x3,&y3);
  325.             path_bezier(x,y,x2,y2,x3,y3);
  326.             dbg wprintf("#bezier (%d)\n",npath);
  327.             cx = x3; cy = y3;
  328.             break;
  329.         case p_stroke:
  330.             dbg wprintf("#stroke (%d) \n",npath);
  331.             path_stroke();
  332.             break;
  333.         case p_fill:
  334.             wprintf("#fill (%d) \n",npath);
  335.             path_fill();
  336.             break;
  337.         case p_lwidth:
  338.             dbg wprintf("#lwidth \n");
  339.             cur_lwidth = getf();
  340.             d_lwidth((int) scx(cur_lwidth));
  341.             break;
  342.         case p_dashlen:
  343.             dbg wprintf("#dashlen \n");
  344.             cur_dashlen = getf();
  345.                         dot=(int)(0.5+d_yscale*cur_dashlen);
  346.                         dot = dot > 0 ? dot : 1;
  347.             d_lstyle(cur_lstyle,dot);
  348.             break;
  349.         case p_lstyle:
  350.             dbg wprintf("#lstyle \n");
  351.             cur_lstyle = getl();
  352.                         dot=(int)(0.5+d_yscale*cur_dashlen);
  353.                         dot = dot > 0 ? dot : 1;
  354.             d_lstyle(cur_lstyle,dot);
  355.             break;
  356.         case p_setcolor:
  357.             x = getl(); x2 = getl(); x3 = getl(); y = getl();
  358.             dbg wprintf("#setcolor %d %d %d f=%d \n",x,x2,x3,y);
  359.             d_setcolor(x,x2,x3,y); /* r,g,b,f */
  360.             break;
  361.         case p_clip:
  362.             dbg wprintf("#clipcurpath \n");
  363.             path_clip();
  364.             break;
  365.         case p_saveclip:
  366.             dbg wprintf("#save clip \n");
  367.             //d_saveclip(bb);
  368.             break;
  369.         case p_restoreclip:
  370.             dbg wprintf("#restore clip \n");
  371.             //bmp_restoreclip(bb);
  372.             break;
  373.         case p_null:
  374.             dbg wprintf("Null \n");
  375.             break;
  376.         default:
  377.             wprintf("Error in PATH codes in .DVI file %d\n",i);
  378.             break;
  379.       }
  380.     }
  381.    wprintf("Finished");
  382.     d_close();
  383. }
  384. void gle_abort(char *s)
  385. {
  386.     wprintf("%s",s);
  387.     exit(1);
  388. }
  389. void path_send(void)
  390. {
  391.     int sx=0,sy=0,cx=0,cy=0,x1,y1,x2,y2,x3,y3;
  392.     int i,j,p1,p2;
  393.  
  394.     d_newpath();
  395.    dbg wprintf("=path send");
  396.     for (i=0;i<npath;i++) {
  397.       switch(path[i]) {
  398.         case p_move:
  399.         sx = path[++i];
  400.         sy = path[++i];
  401.         dbg wprintf("=path move");
  402.         d_pmove(sx,sy);
  403.         cx = sx; cy = sy;
  404.         break;
  405.          case p_line:
  406.         x1 = path[++i];
  407.         y1 = path[++i];
  408.         dbg wprintf("=pline %d %d \n",x1,y1);
  409.         d_pline(x1,y1);
  410.         cx = x1; cy = y1;
  411.         break;
  412.         case p_bezier:
  413.         x1 = path[++i];  y1 = path[++i];
  414.         x2 = path[++i];  y2 = path[++i];
  415.         x3 = path[++i];  y3 = path[++i];
  416.         dbg wprintf("=pbezier %d %d   %d %d   %d %d\n",x1,y1,x2,y2,x3,y3);
  417.         d_pbezier(cx,cy,x1,y1,x2,y2,x3,y3);
  418.         cx = x3; cy = y3;
  419.         break;
  420.         case p_closepath:
  421.         dbg if (cx!=sx || cy!=sy) wprintf("=pclosepath %d %d \n",sx,sy);
  422.         if (cx!=sx || cy!=sy) d_pline(sx,sy);
  423.         cx = sx; cy = sy;
  424.         break;
  425.         default:
  426.         printf("Error in path_fill code path[%d] %d \n",i,path[i]);
  427.       }
  428.     }
  429. }
  430. void path_fill(void)
  431. {
  432.     path_send();
  433.    d_fill();
  434.     //bmp_fill(bb);
  435. }
  436. void path_clip(void)
  437. {
  438.     //path_send();
  439.     //bmp_clip(bb);
  440. }
  441. void path_stroke(void)
  442. {
  443.     int sx=0,sy=0,cx=0,cy=0,x1,y1,x2,y2,x3,y3;
  444.     int i,j,p1,p2;
  445.  
  446.     //bmp_newpath(bb);
  447.     for (i=0;i<npath;i++) {
  448.       switch(path[i]) {
  449.         case p_move:
  450.         sx = path[++i];
  451.         sy = path[++i];
  452.         cx = sx; cy = sy;
  453.         break;
  454.         case p_line:
  455.         x1 = path[++i];
  456.         y1 = path[++i];
  457.         d_line(cx,cy,x1,y1);
  458.         cx = x1; cy = y1;
  459.         break;
  460.         case p_bezier:
  461.         x1 = path[++i];  y1 = path[++i];
  462.         x2 = path[++i];  y2 = path[++i];
  463.         x3 = path[++i];  y3 = path[++i];
  464.         d_bezier(cx,cy,x1,y1,x2,y2,x3,y3);
  465.         cx = x3; cy = y3;
  466.         break;
  467.         case p_closepath:
  468.         if (cx!=sx || cy!=sy) d_line(cx,cy,sx,sy);
  469.         cx = sx; cy = sy;
  470.         break;
  471.         default:
  472.         printf("Error in path_fill code path[%d] %d \n",i,path[i]);
  473.       }
  474.     }
  475. }
  476. void path_move(int  x,int y)
  477. {
  478.     path_alloc();
  479.     path[npath++] = p_move;
  480.     path[npath++] = x;
  481.     path[npath++] = y;
  482. }
  483. void path_line(int x,int y)
  484. {
  485.     path_alloc();
  486.     path[npath++] = p_line;
  487.     path[npath++] = x;
  488.     path[npath++] = y;
  489. }
  490. void path_bezier(int x1, int y1, int x2, int y2,int x3, int y3)
  491. {
  492.     path_alloc();
  493.     path[npath++] = p_bezier;
  494.     path[npath++] = x1;    path[npath++] = y1;
  495.     path[npath++] = x2;    path[npath++] = y2;
  496.     path[npath++] = x3;    path[npath++] = y3;
  497. }
  498. void path_closepath(void)
  499. {
  500.     path_alloc();
  501.     path[npath++] = p_closepath;
  502. }
  503. void path_alloc(void)
  504. {
  505.     static int npa;
  506.     int *a;
  507.  
  508.     if (npath < (npath_alloc-10)) return;
  509.     npath_alloc = 20 + 2 * npath;
  510.     if (npath_alloc<300) npath_alloc = 300;
  511.     wprintf("=== Allocate %d %d \n",npath_alloc,npath);
  512.     a = (int *) calloc(1,npath_alloc*sizeof(int));
  513.     if (a==NULL) {
  514.         gle_abort("Unable to allocate memory for path \n");
  515.     }
  516.     if (path != NULL) {
  517.         dbg wprintf("path reallocate, copy \n");
  518.         memcpy(a,path,(npa)*sizeof(int));
  519.         free(path);
  520.     }
  521.     npa = npath_alloc;
  522.     path = a;
  523. }
  524. void path_free(void)
  525. {
  526.     if (path==NULL) return;
  527.     free(path);
  528.     path = NULL;
  529.     npath = 0;
  530.     npath_alloc = 0;
  531. }
  532.  
  533. /*---------------------------------------------------------------------------*/
  534. static HDC hdc;
  535. static HBRUSH hbrush,hbrush_old;
  536. static HPEN hpen,hpen_old;
  537. static COLORREF pen_color;
  538. static HWND hwndpic;
  539. static int pen_width;
  540. void d_open(double width, double height)
  541. {
  542.     double f,f1,f2,fx,fy;
  543.     double d_scale;
  544.     RECT rect;
  545.     int nxbits,nybits,wstyle;
  546.     pen_color = RGB(0,0,0);
  547.     hbrush = CreateSolidBrush(pen_color);
  548.  
  549.  
  550.     wstyle = WS_VISIBLE  | WS_CHILDWINDOW | WS_THICKFRAME;
  551.  
  552.    if (use_screen) {
  553.         hwndpic = CreateWindow("simple","",wstyle
  554.             ,300,200,300,200
  555.             ,hwndmain, 0, hInst, NULL);
  556.         if (hwndpic==NULL) { emsg("create failed"); return; }
  557.         ShowWindow(hwndpic, SW_SHOW);
  558.        UpdateWindow(hwndpic);
  559.         hdc = GetDC(hwndpic);
  560.         GetClientRect(hwndpic,&rect);
  561.       FillRect(hdc,&rect,GetStockObject(WHITE_BRUSH));
  562.     } else {
  563.         hdc = CreateMetaFile(TEMP_FILE);
  564.     }
  565.     GetClientRect(hwndpic,&rect);
  566.     SetMapMode(hdc,MM_ANISOTROPIC);
  567.     SetWindowExt(hdc,XBITS,YBITS);
  568.     if (use_screen) {
  569.         SetViewportExt(hdc,rect.right,-rect.bottom);
  570.        SetViewportOrg(hdc,0,rect.bottom);
  571.     }
  572.  
  573.     if (hdc==0) wprintf("output hdc is null\n");
  574.     if (hbrush==0)  wprintf("hdc is null\n");
  575.    pen_width = 1;
  576.     hpen = CreatePen(PS_SOLID,pen_width,pen_color);
  577.     hpen_old = SelectObject(hdc,hpen);
  578.     hbrush_old = SelectObject(hdc,hbrush);
  579.  
  580.     {devxcm = width; devycm = height;}
  581.     nxbits = XBITS;
  582.     nybits = YBITS;
  583.     uxcm = width; uycm = height;
  584.  
  585.     d_scale = devxcm / width;
  586.     f = devycm / height;
  587.     if (f<d_scale) d_scale = f;
  588.  
  589.     fx = devxcm / width;
  590.     d_scale = 1;
  591.     fy = devycm / height;
  592.     d_xscale = fx * (nxbits-2) / devxcm;
  593.     d_yscale = fy * (nybits-2) / devycm;
  594. }
  595. void d_close(void)
  596. {
  597.     DeleteMetaFile(CloseMetaFile(hdc));
  598.     DeleteObject(hbrush);
  599.     wprintf("D_CLOSE Success -------\n");
  600.     MessageBeep(0);
  601.     metafile_fix();    // pre-pend fixup head info.
  602.     path_free();
  603. }
  604. void d_line(int cx,int cy,int x,int y)
  605. {
  606.     MoveTo(hdc,cx,cy);
  607.    LineTo(hdc,x,y);
  608. }
  609. void d_lwidth(int width)
  610. {
  611.    pen_width = width;
  612.     DeleteObject(hpen);
  613.     hpen = CreatePen(PS_SOLID,pen_width,pen_color);
  614.     SelectObject(hdc,hpen);
  615. }
  616. void d_bezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
  617. {
  618.     float ax,bx,cx,ay,by,cy,xxx,yyy,t,nstep,xx,yy;
  619.     int dist,i;
  620.  
  621.     dist = abs(x3-x0) + abs(y3-y0);
  622.     nstep = 20;
  623.     if (dist<30) nstep = 10;
  624.     if (dist<10) nstep = 5;
  625.     if (dist<5) nstep = 3;
  626.     if (dist<=2) {
  627.         d_line(x0,y0,x3,y3);
  628.         return;
  629.     }
  630.     cx = (x1-x0)*3;
  631.     bx = (x2-x1)*3-cx;
  632.     ax = x3-x0-cx-bx;
  633.     cy = (y1-y0)*3;
  634.     by = (y2-y1)*3-cy;
  635.     ay = y3-y0-cy-by;
  636.     xx = x0; yy = y0;
  637.     for (i=0;i<=nstep;i++) {
  638.         t = (float) i/nstep;
  639.         xxx = ax*pow(t,3.0) + bx*t*t + cx*t + x0;
  640.         yyy = ay*pow(t,3.0) + by*t*t + cy*t + y0;
  641.         d_line((int) xx,(int) yy, (int) xxx, (int) yyy);
  642.         xx = xxx; yy = yyy;
  643.     }
  644. }
  645. void d_pbezier(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3)
  646. {
  647.     float ax,bx,cx,ay,by,cy,xxx,yyy,t,nstep;
  648.     int dist,i;
  649.  
  650.  
  651.  
  652.     dbg wprintf("pbezier, %d %d   %d %d   %d %d   %d %d \n",x0,y0,x1,y1,x2,y2,x3,y3);
  653.     dist = abs(x3-x0) + abs(y3-y0);
  654.     nstep = 20;
  655.     if (dist<30) nstep = 10;
  656.     if (dist<10) nstep = 5;
  657.     if (dist<5) nstep = 3;
  658.     if (dist<=2) {
  659.         d_pline(x3,y3);
  660.         return;
  661.     }
  662.     cx = (x1-x0)*3;
  663.     bx = (x2-x1)*3-cx;
  664.     ax = x3-x0-cx-bx;
  665.     cy = (y1-y0)*3;
  666.     by = (y2-y1)*3-cy;
  667.     ay = y3-y0-cy-by;
  668.     for (i=0;i<=nstep;i++) {
  669.         t = (float) i/nstep;
  670.         xxx = ax*pow(t,3.0) + bx*t*t + cx*t + x0;
  671.         yyy = ay*pow(t,3.0) + by*t*t + cy*t + y0;
  672.         d_pline((int) xxx,(int) yyy);
  673.     }
  674. }
  675.  
  676. #define MAXPTS 8000
  677. static POINT pts[MAXPTS];
  678. static int ptscnt[100];
  679. static int nptscnt,npts;
  680. void d_newpath(void)
  681. {
  682.     nptscnt = 0;
  683.    npts = 0;
  684. }
  685. static int startx,starty,inaline=false;
  686. void d_pmove(int x, int y)
  687. {
  688.    if (inaline) if (npts>0) d_pclose();
  689.     startx = x; starty = y;
  690.     pts[npts].x = x;
  691.     pts[npts++].y = y;
  692. }
  693. void d_pline(int x, int y)
  694. {
  695.     inaline = true;
  696.     if (npts > (MAXPTS+20)) {wprintf("Too many points in path"); return;}
  697.     pts[npts].x = x;
  698.     pts[npts++].y = y;
  699. }
  700. void d_pclose(void)
  701. {
  702.    int diff;
  703.     if (nptscnt==0) {
  704.         diff = npts;
  705.     } else {
  706.         diff = npts-ptscnt[nptscnt-1];
  707.     }
  708.     if (diff>0)    {
  709.         if ((startx != pts[npts-1].x) || (starty!=pts[npts-1].y)) {
  710.              d_pline(startx,starty);
  711.       }
  712.         ptscnt[nptscnt++] = diff;
  713.     }
  714.    inaline = false;
  715. }
  716. void d_fill(void)
  717. {
  718.     if (inaline) d_pclose();
  719.     wprintf("Polygon nptscnt %d  %d  x=%d y=%d",nptscnt,ptscnt[0],pts[0].x,pts[0].y);
  720.  
  721.     PolyPolygon(hdc,pts,ptscnt,nptscnt);
  722. }
  723. void d_lstyle(int cur_lstyle,int dot)
  724. {
  725. }
  726. void d_setcolor(int r,int g,int b,int f) /* r,g,b,f */
  727. {
  728.     pen_color = RGB(r,g,b);
  729.  
  730.     SelectObject(hdc,hpen_old);
  731.     SelectObject(hdc,hbrush_old);
  732.     DeleteObject(hpen);
  733.     DeleteObject(hbrush);
  734.  
  735.     hbrush = CreateSolidBrush(pen_color);
  736.     hpen = CreatePen(PS_SOLID,pen_width,pen_color);
  737.     SelectObject(hdc,hpen);
  738.     SelectObject(hdc,hbrush);
  739. }
  740.  
  741.  
  742. int wprintf(char *fmt, ...)
  743. {
  744.    va_list argptr;
  745.    int cnt;
  746.     char buffer[2000],*s;
  747.     HDC hdcm;
  748.    int wstyle;
  749.     static HWND hwndmsg;
  750.    RECT rect;
  751.  
  752.    va_start(argptr, fmt);
  753.    cnt = vsprintf(buffer, fmt, argptr);
  754.    va_end(argptr);
  755. //    MessageBox(hwndmain, buffer, "Debug", MB_OK);
  756.  
  757.  
  758.     if (hwndmsg == 0) {
  759.         wstyle = WS_VISIBLE  | WS_CHILDWINDOW | WS_THICKFRAME;
  760.         hwndmsg = CreateWindow("simple","",wstyle
  761.             ,0,200,300,300
  762.             ,hwndmain, 0, hInst, NULL);
  763.         if (hwndmsg==NULL) { emsg("create failed"); return; }
  764.         ShowWindow(hwndmsg, SW_SHOW);
  765.        UpdateWindow(hwndmsg);
  766.         hdcm = GetDC(hwndmsg);
  767.         GetClientRect(hwndmsg,&rect);
  768.       FillRect(hdcm,&rect,GetStockObject(WHITE_BRUSH));
  769.         ReleaseDC(hwndmsg,hdcm);
  770.     }
  771.  
  772.     ScrollWindow(hwndmsg,0,15,NULL,NULL);
  773.     hdcm = GetDC(hwndmsg);
  774.     s = strchr(buffer,'\n');
  775.    if (s!=NULL) *s = 0;
  776.    strcat(buffer,"                            ");
  777.     TextOut(hdcm,0,0,buffer,strlen(buffer));
  778.     ReleaseDC(hwndmsg,hdcm);
  779.  
  780.     return(cnt);
  781. }
  782.  
  783.  
  784. // pre-pend fixup header info.
  785. typedef struct {
  786.     DWORD key; HANDLE hmf;
  787.     RECT bbox; WORD inch;
  788.     DWORD reserved; WORD checksum;
  789. } METAFILEHEADER;
  790. void metafile_fix(void )
  791. {
  792.     WORD *w,xor=0;
  793.    METAFILEHEADER mh;
  794.     int i;
  795.     HFILE hout,hin;
  796.       int sz; char buff[1001];
  797.  
  798.     mh.key = 0x9ac6cdd7L;
  799.     mh.hmf = 0;
  800.     mh.bbox.left = 0;
  801.     mh.bbox.right = XBITS;
  802.     mh.bbox.top = 0;
  803.     mh.bbox.bottom = YBITS;
  804.     mh.inch = 1000;
  805.    mh.reserved = 0;
  806.     w = &mh;
  807.     for (i=0; i<10; i++,w++) {
  808.         xor = xor ^ *w;
  809.    }
  810.    mh.checksum = xor;
  811.  
  812.     hout = _lcreat(OUT_FILE,0);
  813.     if (hout == -1) { wprintf("Couldn't open output file "); return;}
  814.     hin = _lopen(TEMP_FILE,OF_READ);
  815.     if (hin == -1) { wprintf("Couldn't open input file"); return;}
  816.  
  817.  
  818.     _lwrite(hout,&mh,sizeof(mh));
  819.     for (;;) {
  820.         sz = _lread(hin,buff,1000);
  821.         _lwrite(hout,buff,sz);
  822.         if (sz<1000) break;
  823.    }
  824.     if (_lclose(hin)) wprintf("Couldn't close input file");
  825.     if (_lclose(hout)) wprintf("Couldn't close output file");
  826. }
  827.  
  828. char emsg_saved[200];
  829. void emsg(char *s)
  830. {
  831.     int i,j=0;
  832.       wprintf("%s",s);
  833.       return;
  834.  
  835.         for (i=0; i<10000; i++)
  836.             for (j=0; j<1000; j++) ;
  837.  
  838. }
  839. void do_delay(int tm)
  840. {
  841.     int i,j=0,k;
  842.        for (k=0; k<tm; k++)
  843.         for (i=0; i<1000; i++)
  844.             for (j=0; j<1000; j++) ;
  845.  
  846. }
  847.